local oo = require("SharedLibs.BaseLib")
local co = require("SharedLibs.CoroLib")
SyncOp = require("SharedLibs.Ops.SyncOp");
WaitSignal = require("SharedLibs.Signal.WaitSignal");
ISignal = require("SharedLibs.Signal.ISignal");

local CoUtils = {}

--[[
	RawCo和Co可以很简单的互相穿插调用。

	例如，如果想在Co里调用一个RawCo方法，可以简单的把一个它封装在lambda里，然后调用WaitOp：
	local humanoid = co.RawRun(function() 
		return character:WaitForChild("Humanoid") 
	end);

	反之，如果想在RawCo里调用Co，那么可以这样：
	local ret = co.CoRun(function()
		g.delay(5);
		return 123;
	end)
]]

--- 用来将一个对象转换为AsyncOp
function CoUtils.ToOp(obj)
	if obj == nil then return oo.New(SyncOp, nil);
	else 
		local objType = type(obj);
		if objType ~= "table" then
			if objType == "function" then 
				return co.New(obj);
			else
				return oo.New(oo.SyncOp, obj);				
			end
		else			
			if obj.classID == "IAsyncOp" then 
				return obj;
			elseif obj.On and obj.Off then
				return oo.New(WaitSignal, obj);
			else 
				return oo.New(oo.SyncOp, obj);
			end
		end
	end;
end

function CoUtils.IsAsyncOp(object) 
	return object.classID == 'IAsyncOp';
end

function CoUtils.OpToString(op)
	if op == nil then return "nil" end;
	if op.name ~= nil then return op.name end;
	if op.classID == "IAsyncOp" then 
		return co.AsyncOp
	else 
		return "invalid AsyncOp!"
	end; 
end


return CoUtils
